使用憑證!可愛鯨魚穿上了護甲!
圖片來源:Docker (@Docker) / Twitter
架設了 Harbor 但還是只能用 insecure-registries 嗎? 我就不想買憑證也不想沒過幾個月又要去更新憑證...
就來用 OpenSSL 從根憑證開始簽吧!
簡單列一下接下來的步驟~
步驟指令已經統整在 github Day 19 - create-cert.sh 囉~

目標是所有 Node 不設定 insecure-registries 就能取得 Harbor 上的 Image~
先產出根憑證 key,使用 -aes256 可以設定密碼,記得把 password 改掉哦!
openssl genrsa -aes256 -passout pass:password -out ca.key 4096
接著用 key 產生根憑證
openssl req -x509 -new -sha512 -days 365 \
    -subj "/C=TW/ST=Taipei/L=Taipei/O=test/OU=lab/CN=example" \
    -passin pass:password \
    -key ca.key \
    -out ca.pem
C: Country Name (2 個英文字母),國家/地區代號ST: State (全名),州/省份全名O: Organization Name,公司/組織名稱OU: Organizational Unit Name,公司部門/組織單位CN: Common Name,完全限定域名 (FQDN)Ubuntu 的憑證資料夾在 /usr/share/ca-certificates,直接幫剛剛產出的 ca.pem 放到資料夾中就可以了!
可以在裡面多建立一個資料夾便於辨認憑證
sudo mkdir /usr/share/ca-certificates/cluster
sudo cp ca.pem /usr/share/ca-certificates/cluster/
使用指令更新 OS 的憑證,--fresh 會全部重新加載
sudo update-ca-certificates --fresh
如果需要 GUI 版本的可以使用
sudo dpkg-reconfigure ca-certificates
建立 CSR key
這裡不能用
-aes256加密! (Kubernetes 和 Traefik 都不支援)
openssl genrsa -out example.domain.com.key 4096
這裡直接簽 wildcard CN ~
openssl req -sha512 -new \
    -subj "/C=TW/ST=Taiwan/L=Taipei/O=test/OU=lab/CN=*.example.domain.com" \
    -key example.domain.com.key \
    -out example.domain.com.csr
關於 Kubernetes 和 Traefik 不支援 passphrase
Traefik 相關討論:
Kubernetes 相關討論:
先建立終端憑證設定檔,記得修改 DNS~
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=*.example.domain.com
DNS.2=example.domain.com
EOF
使用前面簽的 CA 簽發終端憑證,記得把 password 改成自己設定的!
openssl x509 -req -sha512 -days 365 \
    -extfile v3.ext \
    -passin pass:password \
    -CA ca.pem -CAkey ca.key -CAcreateserial \
    -in example.domain.com.csr \
    -out example.domain.com.pem
cat example.domain.com.pem ca.pem > fullchain.pem
kubectl create secret generic tls-secret -n traefik \
    --from-file=ca.pem \
    --from-file=tls.pem=fullchain.pem \
    --from-file=tls.key=example.domain.com.key
apiVersion: v1
kind: ConfigMap
metadata:
  name: traefik-config
  labels:
    name: traefik-config
  namespace: traefik
data:
  dyn.yaml: |
    tls:
      options:
        default:
          minVersion: VersionTLS12
      stores:
        default:
          defaultCertificate:
            certFile: '/certs/tls.pem'
            keyFile: '/certs/tls.key'
完整檔案可從 github Day 19 - values.yaml 取得
volumes:
  - name: tls-secret
    mountPath: '/certs'
    type: secret
  - name: traefik-config
    mountPath: '/config'
    type: configMap
additionalArguments:
  - '--providers.file.filename=/config/dyn.yaml'
來測試看看憑證吧~
/etc/hosts 設定...10.1.0.1 aaa.example.domain.com harbor.example.domain.com
 
隨便開一個網域下的網址 ( 如: [aaa].example.domain.com )
畫面會顯示 Traefik 的預設頁面 404
接著看網站憑證,可以看到 example 的 rootCA,底下有一個 wildcard 憑證 ( .example.domain.com )
打開網頁可以看到憑證一樣
接著測試 Docker 指令
$ docker login https://harbor.example.domain.com
Username: admin
Password: 
WARNING! Your password will be stored unencrypted in /home/user/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
$ docker image ls alpine
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
alpine       3.16.2    9c6f07244728   7 weeks ago   5.54MB
$ docker tag alpine:3.16.2 harbor.example.domain.com/library/alpine:3.16.2
$ docker push harbor.example.domain.com/library/alpine:3.16.2
The push refers to repository [harbor.example.domain.com/library/alpine]
994393dc58e7: Pushed 
3.16.2: digest: sha256:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870 size: 528
$ docker logout https://harbor.example.domain.com
Removing login credentials for harbor.example.domain.com

 
推送成功~ 
今天簽完自己的憑證並不是要取代外面簽發的憑證
是那些只有內部需要的服務用自己簽的憑證就夠了吧~
剛好很適合目前在亂搞的我~ 